//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

use crate::notice_decode::new_wrong_session_notice;
use proto_gen_rust::org_evaluate_api::org_evaluate_api_client::OrgEvaluateApiClient;
use proto_gen_rust::org_evaluate_api::*;
use tauri::{
    plugin::{Plugin, Result as PluginResult},
    AppHandle, Invoke, PageLoadPayload, Runtime, Window,
};

#[tauri::command]
async fn add_target<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: AddTargetRequest,
) -> Result<AddTargetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.add_target(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == add_target_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("add_target".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn list_target<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: ListTargetRequest,
) -> Result<ListTargetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.list_target(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == list_target_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("list_target".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn update_target<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: UpdateTargetRequest,
) -> Result<UpdateTargetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.update_target(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == update_target_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("update_target".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn remove_target<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: RemoveTargetRequest,
) -> Result<RemoveTargetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.remove_target(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == remove_target_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("remove_target".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn create_evaluate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: CreateEvaluateRequest,
) -> Result<CreateEvaluateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.create_evaluate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == create_evaluate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("create_evaluate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn update_base_for_evaluate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: UpdateBaseForEvaluateRequest,
) -> Result<UpdateBaseForEvaluateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.update_base_for_evaluate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == update_base_for_evaluate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("update_base_for_evaluate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn update_state_for_evaluate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: UpdateStateForEvaluateRequest,
) -> Result<UpdateStateForEvaluateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.update_state_for_evaluate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == update_state_for_evaluate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("update_state_for_evaluate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn list_evaluate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: ListEvaluateRequest,
) -> Result<ListEvaluateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.list_evaluate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == list_evaluate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("list_evaluate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn get_evaluate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: GetEvaluateRequest,
) -> Result<GetEvaluateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.get_evaluate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == get_evaluate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("get_evaluate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn remove_evaluate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: RemoveEvaluateRequest,
) -> Result<RemoveEvaluateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.remove_evaluate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == remove_evaluate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("remove_evaluate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn get_my_evaluate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: GetMyEvaluateRequest,
) -> Result<GetMyEvaluateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.get_my_evaluate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == get_my_evaluate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("get_my_evaluate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn update_my_evaluate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: UpdateMyEvaluateRequest,
) -> Result<UpdateMyEvaluateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgEvaluateApiClient::new(chan.unwrap());
    match client.update_my_evaluate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == update_my_evaluate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("update_my_evaluate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

pub struct OrgEvaluateApiPlugin<R: Runtime> {
    invoke_handler: Box<dyn Fn(Invoke<R>) + Send + Sync + 'static>,
}

impl<R: Runtime> OrgEvaluateApiPlugin<R> {
    pub fn new() -> Self {
        Self {
            invoke_handler: Box::new(tauri::generate_handler![
                add_target,
                list_target,
                update_target,
                remove_target,
                create_evaluate,
                update_base_for_evaluate,
                update_state_for_evaluate,
                list_evaluate,
                get_evaluate,
                remove_evaluate,
                get_my_evaluate,
                update_my_evaluate,
            ]),
        }
    }
}

impl<R: Runtime> Plugin<R> for OrgEvaluateApiPlugin<R> {
    fn name(&self) -> &'static str {
        "org_evaluate_api"
    }
    fn initialization_script(&self) -> Option<String> {
        None
    }

    fn initialize(&mut self, _app: &AppHandle<R>, _config: serde_json::Value) -> PluginResult<()> {
        Ok(())
    }

    fn created(&mut self, _window: Window<R>) {}

    fn on_page_load(&mut self, _window: Window<R>, _payload: PageLoadPayload) {}

    fn extend_api(&mut self, message: Invoke<R>) {
        (self.invoke_handler)(message)
    }
}